package com.vtuzx.kingdee.xqc_core.dao;

import com.mongodb.client.MongoCollection;
import com.vtuzx.core.constant.IVtuzxConst;
import com.vtuzx.core.db.mongo.impl.VtuzxDaoImpl;
import com.vtuzx.core.utils.VtuzxUtil;
import com.vtuzx.kingdee.xqc_core.bean.VtuzxArrayList;
import com.vtuzx.kingdee.xqc_core.constant.BillStatus;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * 即时库存履历Dao
 */
@Component
public class StockTakeTaskDetailDao extends VtuzxDaoImpl {
    /** 集合名 */
    public static final String NAME = "t_sttd_";
    /**
     * 构造
     */
    public StockTakeTaskDetailDao() {
        super(NAME);
    }

    /**
     * 新建单据
     *
     * @param _userId 用户ID
     * @param userName 用户名
     * @param doc 数据
     * @return 单据ID
     */
    public ObjectId insertBill(ObjectId _userId, String userName, String key, Document doc) {
        doc.append("_createUserId", _userId);
        doc.append("createUserName", userName);
        doc.append("_updateUserId", _userId);
        doc.append("updateUserName", userName);
        return insertOne(doc);
    }

    /**
     * 审批单据
     *
     * @param _userId 用户ID
     * @param userName 用户名
     * @param billNo 数据编号
     */
    public void audit(ObjectId _userId, String userName, String billNo) {
        updateOne(Criteria.where("billNo").is(billNo),
                new Document("status", BillStatus.Audit.toString())
                        .append("auditTime", new Date())
                        .append("_auditUserId", _userId)
                        .append("auditUserName", userName));
    }

    /**
     * 反审批单据
     *
     * @param billNo 数据编号
     */
    public void unaudit(String billNo) {
        updateOne(Criteria.where("billNo").is(billNo), new Document("status", BillStatus.Save.toString()));
    }

    /**
     * 保存单据
     *
     * @param billNo 单据号
     * @param status 保存状态
     */
    public void saveBill(boolean isFP, String billNo, Criteria cond, String status) {
        MongoCollection<Document> coll = this.getCollection(NAME + billNo);
        coll.find(cond.getCriteriaObject()).forEach(item -> {
            Document setDoc = new Document();
            if (isFP) {
                setDoc.append("review", status);
            } else {
                setDoc.append("status", status);
            }
            Document updateDoc = new Document("$set", setDoc);
            coll.updateOne(Criteria.where(IVtuzxConst.Key__id).is(item.getObjectId(IVtuzxConst.Key__id)).getCriteriaObject(), updateDoc);
        });
    }

    /**
     * 保存单据
     *
     * @param billNo 单据号
     * @param status 保存状态
     */
    public void auditBill(String billNo, String status) {
        MongoCollection<Document> coll = this.getCollection(NAME + billNo);
        coll.find().forEach(item -> {
            String inventoryStatus = VtuzxUtil.getString(item, "inventoryStatus");
            int bookBoxCount = VtuzxUtil.getInt(item, "bookBoxCount");
            double bookCount = VtuzxUtil.getDouble(item, "bookCount");
            int boxCount;
            double count;
            if ("review".equals(inventoryStatus)) {
                boxCount = VtuzxUtil.getInt(item, "reviewBoxCount");
                count = VtuzxUtil.getDouble(item, "reviewCount");
            } else {
                boxCount = VtuzxUtil.getInt(item, "boxCount");
                count = VtuzxUtil.getDouble(item, "count");
            }
            int TPALBoxCount = boxCount - bookBoxCount;
            double TPALCount = count - bookCount;
            Document setDoc = new Document("TPALCount", TPALCount).append("TPALBoxCount", TPALBoxCount).append("status", status).append("review", status);
            Document updateDoc = new Document("$set", setDoc);
            coll.updateOne(Criteria.where(IVtuzxConst.Key__id).is(item.getObjectId(IVtuzxConst.Key__id)).getCriteriaObject(), updateDoc);
        });
    }
    /**
     * 保存单据
     *
     * @param billNo 单据号
     */
    public void unauditBill(String billNo) {
        MongoCollection<Document> coll = this.getCollection(NAME + billNo);
        coll.find().forEach(item -> {
            Document setDoc = new Document("TPALCount", 1).append("TPALBoxCount", 1);
            Document updateDoc = new Document("$unset", setDoc);
            coll.updateOne(Criteria.where(IVtuzxConst.Key__id).is(item.getObjectId(IVtuzxConst.Key__id)).getCriteriaObject(), updateDoc);
        });
    }

    /**
     * 统计店铺数据
     */
    public Iterator<Document> statStore(ObjectId _storeId, Date from, Date to) {
        Criteria cond = Criteria.where("_storeId").is(_storeId);
        cond.and("from").is("store");
        cond.and(IVtuzxConst.Key_createTime).gte(from).lte(to);

        List<Object> createTimeList = new ArrayList<>();
        createTimeList.add("$createTime");
        createTimeList.add(28800000);
        Document project1 = new Document(IVtuzxConst.Key__id, 0)
                .append("status", 1)
                .append("bjCreateTime", new Document("$add", createTimeList));

        Document project2 = new Document("status", 1)
                .append("createYmd", new Document("$dateToString", new Document("format", "%Y-%m-%d").append("date", "$bjCreateTime")));

        Document groupId = new Document("status", "$status").append("createTime", "$createYmd");

        List<Document> pipes = new ArrayList<>();
        pipes.add(new Document("$match", cond.getCriteriaObject()));
        pipes.add(new Document("$project", project1));
        pipes.add(new Document("$project", project2));
        pipes.add(new Document("$group", new Document(IVtuzxConst.Key__id, groupId).append("count", new Document("$sum", 1))));
        return aggregate(pipes);
    }

    /**
     * 统计店铺数据
     */
    //TODO 排序（1盘没盘也放上面）
    public Iterator<Document> findAggregateList(boolean isFP, String billNo, Criteria cond, Document sort, int pageIndex, int pageSize) {
//        String countCol = isFP? "reviewCount": "count";
//        String boxCountCol = isFP? "reviewBoxCount": "boxCount";
//        Document notSweptBoxDoc = new Document("$subtract", new VtuzxArrayList<>("$bookBoxCount", new Document("$ifNull", new VtuzxArrayList<>("$" + boxCountCol, 0))));
        Document project = new Document()
                .append("materialNo", 1)
                .append("materialName", 1)
                .append("materialSpec", 1)
                .append("batchNo", 1)
                .append("key", 1)
                .append("bookCount", 1)
                .append("bookBoxCount", 1)
                .append("count", 1)
                .append("boxCount", 1)
                .append("reviewCount", 1)
                .append("reviewBoxCount", 1);
//                .append("notSweptBoxCount", notSweptBoxDoc)
//

        List<Document> pipes = new ArrayList<>();
        pipes.add(new Document("$match", cond.getCriteriaObject()));
        pipes.add(new Document("$project", project));
//        pipes.add(new Document("$sort", sort));
        if (pageIndex > 0 && pageSize > 0) {
            pipes.add(new Document("$skip", pageIndex * pageSize));
        }
        if (pageSize > 0) {
            pipes.add(new Document("$limit", pageSize));
        }
        return aggregate(NAME + billNo, pipes);
    }
}
